package org.jeecg.modules.demo.lydasystem.util;

import java.util.*;

public class HJ212MultiParser {

    public static List<Map<String, Object>> parseMultiHJ212(String multiData) {
        List<Map<String, Object>> result = new ArrayList<>();

        if (multiData == null || multiData.trim().isEmpty()) {
            return result;
        }

        // 分割多条消息（以##开头）
        String[] messages = multiData.split("(?=##)");

        for (String message : messages) {
            message = message.trim();
            if (message.isEmpty() || !message.startsWith("##")) {
                continue;
            }

            // 处理单条消息
            Map<String, Object> parsedMessage = parseSingleMessage(message);
            if (!parsedMessage.isEmpty()) {
                result.add(parsedMessage);
            }
        }

        return result;
    }

    private static Map<String, Object> parseSingleMessage(String message) {
        Map<String, Object> result = new LinkedHashMap<>();

        // 检查消息格式是否正确
        if (!message.startsWith("##") || message.length() < 10) {
            return result;
        }

        // 提取长度字段（##后面的4位数字）
        String lengthField = message.substring(2, 6);
        result.put("Length", lengthField);

        // 提取CRC校验码（最后4位）
        String crcCode = message.substring(message.length() - 4);
        result.put("CRC", crcCode);

        // 提取消息主体（去掉##+长度和CRC）
        String messageBody = message.substring(6, message.length() - 4);

        // 解析消息主体
        Map<String, Object> messageData = parseHJ212Body(messageBody);
        result.putAll(messageData);

        return result;
    }

    private static Map<String, Object> parseHJ212Body(String data) {
        Map<String, Object> result = new LinkedHashMap<>();

        if (data == null || data.trim().isEmpty()) {
            return result;
        }

        // 分割外层数据段（以分号分隔）
        String[] segments = data.split(";", -1); // 使用-1保留空字段

        for (String segment : segments) {
            segment = segment.trim();
            if (segment.isEmpty()) {
                continue;
            }
            // 处理CP数据段（包含&&的数据）
            if (segment.startsWith("CP=")) {
                Map<String, Object> cpData = parseCPDataToMap(data);

                result.put("CP", cpData);
            }

            // 处理QN数据段（时间戳）
            if (segment.startsWith("QN=")) {
                result.put("QN", segment.substring(3));
            }
            // 处理ST数据段（系统类型）
            else if (segment.startsWith("ST=")) {
                result.put("ST", segment.substring(3));
            }
            // 处理CN数据段（命令编号）
            else if (segment.startsWith("CN=")) {
                result.put("CN", segment.substring(3));
            }
            // 处理PW数据段（密码）
            else if (segment.startsWith("PW=")) {
                result.put("PW", segment.substring(3));
            }
            // 处理MN数据段（设备标识）
            else if (segment.startsWith("MN=")) {
                result.put("MN", segment.substring(3));
            }
            // 处理Flag数据段（标志位）
            else if (segment.startsWith("Flag=")) {
                result.put("Flag", segment.substring(5));
            }
            // 处理CP数据段（包含&&的数据）
            else if (segment.startsWith("CP=")) {
                Map<String, Object> cpData = parseCPDataToMap(data);
                result.put("CP", cpData);
            }
            // 处理其他未知字段
            else if (segment.contains("=")) {
                String[] parts = segment.split("=", 2);
                if (parts.length == 2) {
                    result.put(parts[0], parts[1]);
                }
            }
        }

        return result;
    }

    private static Map<String, Object> parseCPDataToMap(String cpSegment) {
        Map<String, Object> cpData = new LinkedHashMap<>();

        // 提取CP=后面的内容
        String cpContent = cpSegment.split("CP=")[1]; // 去掉"CP="

        // 检查是否包含&&
        if (cpContent.startsWith("&&") && cpContent.endsWith("&&")) {
            // 去掉前后的&&
            String innerContent = cpContent.substring(2, cpContent.length() - 2);

            // 分割内部数据（以分号分隔）
            String[] innerSegments = innerContent.split(";");

            for (String innerSegment : innerSegments) {
                // 如果内部数据段包含逗号分隔的多个数据（如w20089-Rtd=1.9333,w20089-Flag=N）
                if (innerSegment.contains(",")) {
                    String[] subSegments = innerSegment.split(",");
                    Map<String, String> measurementData = new LinkedHashMap<>();

                    for (String subSegment : subSegments) {
                        parseKeyValue(subSegment, measurementData);
                    }

                    // 获取测量项名称（去掉-Rtd或-Flag后缀）
                    String firstKey = subSegments[0].split("=")[0];
                    String itemName = extractItemName(firstKey);
                    cpData.put(itemName, measurementData);
                } else {
                    parseKeyValues(innerSegment, cpData);
                }
            }
        } else {
            // 如果没有&&，直接解析键值对
            parseKeyValues(cpSegment, cpData);
        }

        return cpData;
    }


    // 通用的键值对解析方法
    private static void parseKeyValues(String segment, Map<String, Object> map) {
        if (segment.contains("=")) {
            String[] parts = segment.split("=", 2);
            if (parts.length == 2) {
                map.put(parts[0].trim(), parts[1].trim());
            }
        }
    }

    // 重载方法，用于Map<String, String>
    private static void parseKeyValue(String segment, Map<String, String> map) {
        if (segment.contains("=")) {
            String[] parts = segment.split("=", 2);
            if (parts.length == 2) {
                map.put(parts[0].trim(), parts[1].trim());
            }
        }
    }


    private static Map<String, Object> parseCPData(String cpSegment) {
        Map<String, Object> cpData = new LinkedHashMap<>();

        // 提取CP=后面的内容
        String cpContent = cpSegment.substring(3); // 去掉"CP="

        // 检查是否包含&&
        if (cpContent.startsWith("&&") && cpContent.endsWith("&&")) {
            // 去掉前后的&&
            String innerContent = cpContent.substring(2, cpContent.length() - 2);

            // 分割内部数据（以分号分隔）
            String[] innerSegments = innerContent.split(";", -1);

            for (String innerSegment : innerSegments) {
                innerSegment = innerSegment.trim();
                if (innerSegment.isEmpty()) {
                    continue;
                }

                // 处理简单键值对（如DataTime=20251030074000）
                if (innerSegment.contains("=") && !innerSegment.contains(",")) {
                    String[] parts = innerSegment.split("=", 2);
                    if (parts.length == 2) {
                        cpData.put(parts[0], parts[1]);
                    }
                }
                // 处理包含逗号分隔的多个数据（如w20089-Rtd=1.9333,w20089-Flag=N）
                else if (innerSegment.contains(",")) {
                    String[] subSegments = innerSegment.split(",");
                    Map<String, String> measurementData = new LinkedHashMap<>();

                    for (String subSegment : subSegments) {
                        subSegment = subSegment.trim();
                        if (subSegment.contains("=")) {
                            String[] parts = subSegment.split("=", 2);
                            if (parts.length == 2) {
                                measurementData.put(parts[0], parts[1]);
                            }
                        }
                    }

                    // 获取测量项名称（去掉各种后缀）
                    if (!measurementData.isEmpty()) {
                        String firstKey = measurementData.keySet().iterator().next();
                        String itemName = extractItemName(firstKey);
                        cpData.put(itemName, measurementData);
                    }
                }
            }
        }

        return cpData;
    }

    // 提取测量项名称（去掉-Rtd、-Flag、-Max、-Min、-Avg、-Cou等后缀）
    private static String extractItemName(String key) {
        return key.replace("-Rtd", "")
                .replace("-Flag", "")
                .replace("-Max", "")
                .replace("-Min", "")
                .replace("-Avg", "")
                .replace("-Cou", "");
    }

    // 测试方法
    public static void main(String[] args) {
        // 测试数据 - 只使用第一条消息进行测试
        String testMessage = "##0620ST=32;CN=2051;PW=dsj123456;MN=dsj;Flag=0;CP=&&DataTime=20251030074000;w20089-Max=2.1128,w20089-Min=2.1128,w20089-Avg=2.1128,w20089-Cou=0.0,w20089-Flag=N;w20111-Max=0.0,w20111-Min=0.0,w20111-Avg=0.0,w20111-Cou=0.0,w20111-Flag=N;w20120-Max=0.0112,w20120-Min=0.0112,w20120-Avg=0.0112,w20120-Cou=0.0,w20120-Flag=N;w20115-Max=0.0001,w20115-Min=0.0001,w20115-Avg=0.0001,w20115-Cou=0.0,w20115-Flag=N;w20119-Max=0.0179,w20119-Min=0.0179,w20119-Avg=0.0179,w20119-Cou=0.0,w20119-Flag=N;w01001-Max=8.72,w01001-Min=8.71,w01001-Avg=8.72,w01001-Cou=0.0,w01001-Flag=N;e01203-Max=0,e01203-Min=0,e01203-Avg=0,e01203-Cou=0,e01203-Flag=N&&30C0";

        System.out.println("测试单条消息解析:");
        Map<String, Object> parsedMessage = parseSingleMessage(testMessage);
        printMessage(parsedMessage, 1);

        // 测试完整的多条消息
        String multiHJ212Data = "##0620ST=32;CN=2051;PW=dsj123456;MN=dsj;Flag=0;CP=&&DataTime=20251030074000;w20089-Max=2.1128,w20089-Min=2.1128,w20089-Avg=2.1128,w20089-Cou=0.0,w20089-Flag=N;w20111-Max=0.0,w20111-Min=0.0,w20111-Avg=0.0,w20111-Cou=0.0,w20111-Flag=N;w20120-Max=0.0112,w20120-Min=0.0112,w20120-Avg=0.0112,w20120-Cou=0.0,w20120-Flag=N;w20115-Max=0.0001,w20115-Min=0.0001,w20115-Avg=0.0001,w20115-Cou=0.0,w20115-Flag=N;w20119-Max=0.0179,w20119-Min=0.0179,w20119-Avg=0.0179,w20119-Cou=0.0,w20119-Flag=N;w01001-Max=8.72,w01001-Min=8.71,w01001-Avg=8.72,w01001-Cou=0.0,w01001-Flag=N;e01203-Max=0,e01203-Min=0,e01203-Avg=0,e01203-Cou=0,e01203-Flag=N&&30C0\n" +
                "##0319ST=32;CN=2011;PW=dsj123456;MN=dsj;Flag=0;CP=&&DataTime=20251030075000;w20089-Rtd=2.1128,w20089-Flag=N;w20111-Rtd=0.0,w20111-Flag=N;w20120-Rtd=0.0112,w20120-Flag=N;w20115-Rtd=0.0001,w20115-Flag=N;w20119-Rtd=0.0179,w20119-Flag=N;w01001-Rtd=8.71,w01001-Flag=N;e01203-Rtd=0,e01203-Flag=N;e01204-Rtd=67133.35,e01204-Flag=N&&B681";

        System.out.println("\n\n测试多条消息解析:");
        List<Map<String, Object>> parsedMessages = parseMultiHJ212(multiHJ212Data);

        for (int i = 0; i < parsedMessages.size(); i++) {
            printMessage(parsedMessages.get(i), i + 1);
        }
    }

    private static void printMessage(Map<String, Object> message, int index) {
        System.out.println("第 " + index + " 条消息:");
        System.out.println("  长度字段: " + message.get("Length"));
        System.out.println("  CRC校验: " + message.get("CRC"));
        System.out.println("  系统类型(ST): " + message.get("ST"));
        System.out.println("  命令编号(CN): " + message.get("CN"));
        System.out.println("  设备标识(MN): " + message.get("MN"));

        if (message.containsKey("QN")) {
            System.out.println("  时间戳(QN): " + message.get("QN"));
        }

        if (message.containsKey("CP")) {
            @SuppressWarnings("unchecked")
            Map<String, Object> cpData = (Map<String, Object>) message.get("CP");
            System.out.println("  数据时间: " + cpData.get("DataTime"));

            // 显示所有测量项
            for (Map.Entry<String, Object> entry : cpData.entrySet()) {
                if (entry.getValue() instanceof Map) {
                    @SuppressWarnings("unchecked")
                    Map<String, String> measurement = (Map<String, String>) entry.getValue();
                    System.out.println("  测量项 " + entry.getKey() + ": " + measurement);
                }
            }
        }
        System.out.println("------------------------------------------");
    }
}